Skip to content

Install Modal image dependencies from pinned uv.lock exports#608

Closed
anth-volk wants to merge 2 commits into
mainfrom
modal-images-from-lockfile
Closed

Install Modal image dependencies from pinned uv.lock exports#608
anth-volk wants to merge 2 commits into
mainfrom
modal-images-from-lockfile

Conversation

@anth-volk

Copy link
Copy Markdown
Contributor

Fixes #607

Stacked on #603 — merge that first; this diff shrinks to its own commit afterwards.

Problem

Modal image pip_install calls used loose ranges (logfire>=3.0.0), so any image-layer cache miss re-resolved packages fresh against PyPI. Image dependency versions drifted from the tested uv.lock environment, and breakage surfaced only in post-merge beta integration tests — #602 (gateway crash-looping on logfire's undeclared importlib_metadata dependency) is the incident this enables.

Change

  • Define the image package sets as PEP 735 dependency groups (modal-simulation-image, modal-gateway-image) in the simulation project's pyproject.toml, resolved inside the same uv.lock as the project — so image versions match what tests run against (e.g. images now get the tested logfire==4.6.0, not whatever is newest).
  • Export them to checked-in pinned requirements files (requirements/modal-*.txt, full transitive closure) via scripts/export-modal-image-requirements.sh; images install with pip_install_from_requirements.
  • make update re-exports after relocking, so the daily dependency-update workflow keeps images in lockstep with the lock.
  • New unit tests fail CI when the exports drift from uv.lock, when any requirement is unpinned, or if the exports ever stop pinning logfire/importlib-metadata (Beta gateway crash-loops: logfire import fails with ModuleNotFoundError (importlib_metadata) in rebuilt Modal images #602 regression guard).
  • README section documenting the mechanism.

Tests

  • uv run pytest tests/: 331 passed (6 new)
  • Real-Modal import check: both image definitions construct against modal 1.4.2
  • make format: clean

Staging image layers for the new chain will be prewarmed off the deploy path before merge.

🤖 Generated with Claude Code

anth-volk and others added 2 commits July 3, 2026 18:46
logfire >=4.7 imports importlib_metadata unconditionally on Python 3.13
but stopped receiving it transitively, so the freshly rebuilt gateway
and simulation images crash on import logfire. The gateway ASGI factory
died at startup, hanging every request past Modal's HTTP window (303
redirects), which failed all beta integration tests and blocked the
production deploy of the observability PR (#594).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Modal images resolved their packages fresh at image-build time from
loose pip_install ranges, so image dependencies drifted from the tested
uv.lock environment; issue #602 (logfire resolving to a release with an
undeclared importlib_metadata dependency) is the failure mode. Define
the image package sets as uv dependency groups resolved inside uv.lock,
export them to checked-in pinned requirements files, and install the
images from those. make update re-exports after relocking and a unit
test fails CI when the exports drift from the lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@anth-volk

Copy link
Copy Markdown
Contributor Author

Superseded by the simulation service restructure (#609): this PR's commit (8eff8fb) re-lands verbatim as commit 2 of that PR, and the gateway half is replaced by a dedicated gateway project whose image installs via uv_sync from its own lockfile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Modal images resolve dependencies fresh at build time instead of installing from a lockfile

1 participant